package org.dromara.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.Device;
import org.dromara.system.domain.DeviceAlarm;
import org.dromara.system.domain.bo.DeviceAlarmBo;
import org.dromara.system.domain.bo.ProcessDeviceAlarmBo;
import org.dromara.system.domain.vo.DeviceAlarmVo;
import org.dromara.system.mapper.DeviceAlarmMapper;
import org.dromara.system.mapper.DeviceCollectMapper;
import org.dromara.system.mapper.DeviceUserGroupMapper;
import org.dromara.system.mapper.SysUserRoleMapper;
import org.dromara.system.service.IDeviceAlarmService;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 设备报警Service业务层处理
 *
 * @author Lion Li
 * @date 2024-10-21
 */
@RequiredArgsConstructor
@Service
public class DeviceAlarmServiceImpl implements IDeviceAlarmService {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private final DeviceAlarmMapper baseMapper;

    private final DeviceCollectMapper deviceCollectMapper;

    private final SysUserRoleMapper userRoleMapper;
    private final DeviceUserGroupMapper deviceUserGroupMapper;

    /**
     * 查询设备报警
     *
     * @param id 主键
     * @return 设备报警
     */
    @Override
    public DeviceAlarmVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询设备报警列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 设备报警分页列表
     */
    @Override
    public TableDataInfo<DeviceAlarmVo> queryPageList(DeviceAlarmBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<DeviceAlarm> lqw = buildQueryWrapper(bo);
        Page<DeviceAlarmVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        if (!result.getRecords().isEmpty()) {
            for (DeviceAlarmVo record : result.getRecords()) {
                record.setDeviceGroupName(baseMapper.selectDeviceGroupNameById(record.getDeviceGroup()));
                record.setTunnelName(getTunnelName(record.getTunnelId()));

            }
        }
        return TableDataInfo.build(result);
    }

    private String getTunnelName(Long tunnelId) {
        Map<Long, String> tunnelMap = new HashMap<>();
        tunnelMap.put(1L, "应天大街隧道");
        tunnelMap.put(2L, "定淮门隧道");
        tunnelMap.put(3L, "江心洲大桥");
        return tunnelMap.get(tunnelId);
    }


    /**
     * 查询符合条件的设备报警列表
     *
     * @param bo 查询条件
     * @return 设备报警列表
     */
    @Override
    public List<DeviceAlarmVo> queryList(DeviceAlarmBo bo) {
        LambdaQueryWrapper<DeviceAlarm> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public Boolean processAlarm(Long id, ProcessDeviceAlarmBo bo) {
        DeviceAlarm deviceAlarm = baseMapper.selectById(id);
        baseMapper.updateVariableStatusById(deviceAlarm.getVariableId());
        return baseMapper.updateAlarmDataById(id, bo.getTransactor(), bo.getRemark(), new Date());
    }

    @Override
    public DeviceAlarm getDeviceAlarm(Long variableId, Long level) {
        return baseMapper.selectOne(new LambdaQueryWrapper<DeviceAlarm>().eq(DeviceAlarm::getVariableId, variableId).eq(DeviceAlarm::getLevel, level).eq(DeviceAlarm::getStatus, 0));
    }

    @Override
    public void update(DeviceAlarm deviceAlarm) {
        baseMapper.updateById(deviceAlarm);
    }


    private LambdaQueryWrapper<DeviceAlarm> buildQueryWrapper(DeviceAlarmBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<DeviceAlarm> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getDeviceId() != null, DeviceAlarm::getDeviceId, bo.getDeviceId());
        lqw.eq(bo.getDeviceGroup() != null, DeviceAlarm::getDeviceGroup, bo.getDeviceGroup());
        lqw.eq(bo.getLevel() != null, DeviceAlarm::getLevel, bo.getLevel());
        if (params.get("deviceName") != null && !"".equals(params.get("deviceName"))) {
            lqw.like(DeviceAlarm::getDeviceName, "%" + bo.getDeviceName() + "%");
        }
        Long userId = LoginHelper.getUserId();
        if (bo.getCollect() != null) {
            List<Long> deviceIds = deviceCollectMapper.getDeviceIds(userId);
            if (!deviceIds.isEmpty()) {
                lqw.in(DeviceAlarm::getDeviceId, deviceIds);
            }else {
                lqw.eq(DeviceAlarm::getDeviceId, 0);
            }
        }
        boolean roleId = LoginHelper.isSuperAdmin(userId);
        if (!roleId){
            List<Long> longs = deviceUserGroupMapper.selectGroupIdListByUserId(userId);
            if (!longs.isEmpty()){
                lqw.in(DeviceAlarm::getDeviceGroup, longs);
            }else {
                lqw.eq(DeviceAlarm::getId, 0L);
            }
        }



        // 时间范围查询
        if (bo.getStartTime() != null && !bo.getStartTime().isBlank() && bo.getEndTime() != null && !bo.getEndTime().isBlank()) {
            LocalDate startDate = LocalDate.parse(bo.getStartTime(), DATE_TIME_FORMATTER);
            LocalDate endDate = LocalDate.parse(bo.getEndTime(), DATE_TIME_FORMATTER);
            lqw.between(DeviceAlarm::getCreateTime, startDate.atStartOfDay(), endDate.atTime(23, 59, 59));
        } else if (bo.getStartTime() != null && !bo.getStartTime().isBlank()) {
            LocalDate startDate = LocalDate.parse(bo.getStartTime(), DATE_TIME_FORMATTER);
            lqw.ge(DeviceAlarm::getCreateTime, startDate.atStartOfDay());
        } else if (bo.getEndTime() != null && !bo.getEndTime().isBlank()) {
            LocalDate endDate = LocalDate.parse(bo.getEndTime(), DATE_TIME_FORMATTER);
            lqw.le(DeviceAlarm::getCreateTime, endDate.atTime(23, 59, 59));
        }
        lqw.eq(bo.getStatus() != null, DeviceAlarm::getStatus, bo.getStatus());
        lqw.orderByDesc(DeviceAlarm::getCreateTime);
        return lqw;
    }
}
